package com.itlong.cloud.property.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.PO.DeviceBusinessChangeLogPO;
import com.itlong.cloud.POJO.PO.DeviceMediaGatePO;
import com.itlong.cloud.POJO.PO.DeviceMediaInfoPO;
import com.itlong.cloud.POJO.VO.property.DeviceMediaAttacheFileInfoVO;
import com.itlong.cloud.POJO.VO.property.DeviceMediaBindAddressVO;
import com.itlong.cloud.POJO.VO.property.DeviceMediaGateInfoVO;
import com.itlong.cloud.POJO.VO.property.DeviceMediaInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.CloudIntercomTypeEnum;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.SmartCommunityEnum;
import com.itlong.cloud.property.dao.IDeviceMediaGateDao;
import com.itlong.cloud.property.dao.IDeviceMediaInfoDao;
import com.itlong.cloud.property.service.IDeviceMediaGateService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <desc>
 * 门口机设备多媒体信息处理接口实现.
 * </desc>
 *
 * @createDate 2017-10-23
 */
@Service
public class DeviceMediaGateServiceImpl implements IDeviceMediaGateService {

    @Autowired
    private IDeviceMediaInfoDao iDeviceMediaInfoDao; //设备多媒体信息数据库访问对象
    @Autowired
    private IDeviceMediaGateDao iDeviceMediaGateDao; //门口机设备多媒体服务信息数据库访问对象

    @Autowired
    private MessageSender messageSender; //RabitMQ发送

    /**
     * <desc>
     *      保存单个门口机设备多媒体信息
     * </desc>
     *
     * @param deviceMediaGateSaveDTO  保存门口机设备多媒体信息数据传输对象
     * @return 受影响的行数
     * @author Lix
     * @createDate 2017-10-23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer saveDeviceMediaInfo(DeviceMediaGateSaveDTO deviceMediaGateSaveDTO) throws Exception {
        String mediaId = LogicIdUtil.bussinessId();
        Date saveTime = new Date();
        //保存设备多媒体信息
        DeviceMediaInfoPO deviceMediaInfoPO = new DeviceMediaInfoPO();
        deviceMediaInfoPO.setMediaId(mediaId);
        deviceMediaInfoPO.setProjectId(deviceMediaGateSaveDTO.getProjectId());
        deviceMediaInfoPO.setTitle(deviceMediaGateSaveDTO.getTitle());
        deviceMediaInfoPO.setChildrenType(CloudIntercomTypeEnum.GATE.getType());
        deviceMediaInfoPO.setType(deviceMediaGateSaveDTO.getType());
        deviceMediaInfoPO.setContent(deviceMediaGateSaveDTO.getContent());
        deviceMediaInfoPO.setStatus(deviceMediaGateSaveDTO.getStatus());
        deviceMediaInfoPO.setAttacheFile(deviceMediaGateSaveDTO.getAttacheFiles());
        deviceMediaInfoPO.setAttacheFileUrl(deviceMediaGateSaveDTO.getAttacheFileUrls());
        deviceMediaInfoPO.setAttacheFileMd5(deviceMediaGateSaveDTO.getAttacheFileMd5());
        deviceMediaInfoPO.setCreateTime(saveTime);
        deviceMediaInfoPO.setUpdateTime(saveTime);

        //保存多媒体信息到数据库（事务保护）
        int intRes =  this.saveDeviceMediaInfoToDB(deviceMediaInfoPO,deviceMediaGateSaveDTO);



        //仅多媒体资源添加时状态为启用时才通知云对讲更新
        if (NumberHandlerUtil.isEqual(deviceMediaInfoPO.getStatus(),DataStatusEnum.NORMAL.getType())){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("projectId",deviceMediaGateSaveDTO.getProjectId());
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                    = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_MEDIA,jsonObject,deviceMediaGateSaveDTO.getProjectId());
            List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
            deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data",deviceBusinessChangeLogPOS);
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        }
        return intRes;
    }

    /**
     * <desc>
     *      保存单个门口机设备多媒体信息到数据库
     * </desc>
     *
     * @param deviceMediaGateSaveDTO  保存门口机设备多媒体信息数据传输对象
     * @return 受影响的行数
     * @author Lix
     * @createDate 2017-10-23
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer saveDeviceMediaInfoToDB(DeviceMediaInfoPO deviceMediaInfoPO,DeviceMediaGateSaveDTO deviceMediaGateSaveDTO) throws Exception {
        iDeviceMediaInfoDao.save(SqlUtil.durableData(deviceMediaInfoPO, PlatformConstants.TABLE_SAVE));

        //批量保存门口机多媒体资源-服务地址关联信息
        List<Map<String,Object>> batchParams = new ArrayList<>();
        for (DeviceMediaBindAddressDTO deviceMediaBindAddressDTO:deviceMediaGateSaveDTO.getBindAddressInfo())
        {
            DeviceMediaGatePO deviceMediaGatePO = new DeviceMediaGatePO();
            deviceMediaGatePO.setMediaId(deviceMediaInfoPO.getMediaId());
            deviceMediaGatePO.setProjectId(deviceMediaGateSaveDTO.getProjectId());
            deviceMediaGatePO.setBuildId(deviceMediaBindAddressDTO.getBuildId());
            deviceMediaGatePO.setUnitId(deviceMediaBindAddressDTO.getUnitId());
            deviceMediaGatePO.setCreateTime(deviceMediaInfoPO.getCreateTime());
            deviceMediaGatePO.setUpdateTime(deviceMediaInfoPO.getCreateTime());
            deviceMediaGatePO.setStatus(DataStatusEnum.NORMAL.getType());
            batchParams.add(SqlUtil.durableData(deviceMediaGatePO, PlatformConstants.TABLE_SAVE));
        }
        int intRes =  iDeviceMediaGateDao.batchSave(batchParams);

        return intRes;
    }

    /**
     * <desc>
     *     修改单个门口机设备多媒体信息【根据多媒体Id（mediaId）】
     * </desc>
     *
     * @param deviceMediaGateUpdateDTO 修改门口机设备多媒体信息数据传输对象
     * @return 受影响的行数
     * @author Lix
     * @createDate 2017-10-23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer updateDeviceMediaGateInfo(DeviceMediaGateUpdateDTO deviceMediaGateUpdateDTO) throws Exception {
        Date updateTime = new Date();
        //修改设备多媒体信息
        DeviceMediaInfoPO deviceMediaInfoPO = new DeviceMediaInfoPO();
        deviceMediaInfoPO.setMediaId(deviceMediaGateUpdateDTO.getMediaId());
        deviceMediaInfoPO.setProjectId(null);
        deviceMediaInfoPO.setTitle(deviceMediaGateUpdateDTO.getTitle());
        deviceMediaInfoPO.setChildrenType(CloudIntercomTypeEnum.GATE.getType());
        deviceMediaInfoPO.setStatus(deviceMediaGateUpdateDTO.getStatus());
        deviceMediaInfoPO.setType(deviceMediaGateUpdateDTO.getType());
        deviceMediaInfoPO.setContent(deviceMediaGateUpdateDTO.getContent());
        deviceMediaInfoPO.setAttacheFile(deviceMediaGateUpdateDTO.getAttacheFiles());
        deviceMediaInfoPO.setAttacheFileUrl(deviceMediaGateUpdateDTO.getAttacheFileUrls());
        deviceMediaInfoPO.setAttacheFileMd5(deviceMediaGateUpdateDTO.getAttacheFileMd5());
        deviceMediaInfoPO.setCreateTime(null);
        deviceMediaInfoPO.setUpdateTime(updateTime);

        //更新多媒体信息到数据库（事务保护）
        Integer intRes = this.updateDeviceMediaGateInfoToDB(deviceMediaInfoPO,deviceMediaGateUpdateDTO);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("projectId",deviceMediaGateUpdateDTO.getProjectId());
        DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_MEDIA,jsonObject,deviceMediaGateUpdateDTO.getProjectId());
        List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
        deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",deviceBusinessChangeLogPOS);
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

        return intRes;
    }

    /**
     * <desc>
     *     修改单个门口机设备多媒体信息【根据多媒体Id（mediaId）】
     * </desc>
     * @param  deviceMediaInfoPO 多媒体信息数据库对象
     * @param deviceMediaGateUpdateDTO 修改门口机设备多媒体信息数据传输对象
     * @return 受影响的行数
     * @author Lix
     * @createDate 2017-10-23
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateDeviceMediaGateInfoToDB(DeviceMediaInfoPO deviceMediaInfoPO,DeviceMediaGateUpdateDTO deviceMediaGateUpdateDTO) throws Exception {
        iDeviceMediaInfoDao.update(SqlUtil.durableData(deviceMediaInfoPO, PlatformConstants.TABLE_UPDATE));
        //修改门口机关联信息
        iDeviceMediaGateDao.removeOne(deviceMediaGateUpdateDTO.getMediaId());

        List<Map<String,Object>> batchParams = new ArrayList<>();
        for (DeviceMediaBindAddressDTO deviceMediaBindAddressDTO:deviceMediaGateUpdateDTO.getBindAddressInfo())
        {
            DeviceMediaGatePO deviceMediaGatePO = new DeviceMediaGatePO();
            deviceMediaGatePO.setMediaId(deviceMediaGateUpdateDTO.getMediaId());
            deviceMediaGatePO.setProjectId(deviceMediaGateUpdateDTO.getProjectId());
            deviceMediaGatePO.setBuildId(deviceMediaBindAddressDTO.getBuildId());
            deviceMediaGatePO.setUnitId(deviceMediaBindAddressDTO.getUnitId());
            deviceMediaGatePO.setCreateTime(deviceMediaInfoPO.getUpdateTime());
            deviceMediaGatePO.setUpdateTime(deviceMediaInfoPO.getUpdateTime());
            deviceMediaGatePO.setStatus(DataStatusEnum.NORMAL.getType());
            batchParams.add(SqlUtil.durableData(deviceMediaGatePO, PlatformConstants.TABLE_SAVE));
        }
        Integer intRes = iDeviceMediaGateDao.batchSave(batchParams);

        return intRes;

    }

    /**
     * <desc>
     * 根据多媒体资源Id获取门口机多媒体资源及其对应的地址列表.
     * </desc>
     *
     * @param mediaId 多媒体资源ID
     * @return 门口机多媒体资源及其对应的地址列表
     * @author LewisLouis
     * @createDate 2017-11-21
     */
    @Override
    public DeviceMediaGateInfoVO getOneMediaGateInfo(String mediaId) {
        DeviceMediaInfoVO mediaInfoVO = iDeviceMediaInfoDao.getOneMediaInfo(mediaId);
        if (mediaInfoVO == null){
            return  null;
        }
        DeviceMediaGateInfoVO deviceMediaGateInfoVO = new DeviceMediaGateInfoVO();
        BeanUtils.copyProperties(mediaInfoVO,deviceMediaGateInfoVO);

        List<DeviceMediaAttacheFileInfoVO> deviceMediaAttacheFileInfoVOS = new ArrayList<>();
        List<String> attacheFileUrls = castStrToListByCommaChar(mediaInfoVO.getAttacheFileUrl());
        List<String> attacheFileNames = castStrToListByCommaChar(mediaInfoVO.getAttacheFile());
        List<String> attacheFileMd5s = castStrToListByCommaChar(mediaInfoVO.getAttacheFileMd5());

        for (int fileIndex = 0; fileIndex< attacheFileNames.size();fileIndex++){
            String fileName = attacheFileNames.get(fileIndex);
            DeviceMediaAttacheFileInfoVO deviceMediaAttacheFileInfoVO = new DeviceMediaAttacheFileInfoVO();
            deviceMediaAttacheFileInfoVO.setFileName(fileName);
            if (attacheFileUrls.size() > fileIndex){
                deviceMediaAttacheFileInfoVO.setAttacheFileUrl(attacheFileUrls.get(fileIndex));
            }
            if (attacheFileMd5s.size() > fileIndex){
                deviceMediaAttacheFileInfoVO.setFileMd5(attacheFileMd5s.get(fileIndex));
            }
            deviceMediaAttacheFileInfoVOS.add(deviceMediaAttacheFileInfoVO);
        }
        deviceMediaGateInfoVO.setAttacheFiles(deviceMediaAttacheFileInfoVOS);

        List<DeviceMediaBindAddressVO> deviceMediaBindAddressVOList = iDeviceMediaGateDao.getOneMediaGateInfo(mediaId);
        deviceMediaGateInfoVO.setBindAddressInfos(deviceMediaBindAddressVOList);
        return deviceMediaGateInfoVO;
    }

    /**
     * <desc>
     * 分页查询指定的门口机多媒体资源绑定的地址列表
     * </desc>
     *
     * @param deviceMediaGateBindAddressGetPageDTO 分页查询门口机多媒体资源绑定的住址列表参数
     * @return 绑定的地址列表
     * @author LouisLewis
     * @createDate 2017-11-21
     */
    @Override
    public Page<DeviceMediaBindAddressVO> getPageOneMediaGateBindAddressInfos(
            DeviceMediaGateBindAddressGetPageDTO deviceMediaGateBindAddressGetPageDTO) throws Exception{

        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(deviceMediaGateBindAddressGetPageDTO);;

        Page<DeviceMediaBindAddressVO> page = new Page<>();
        page.getPage().setPageSize(deviceMediaGateBindAddressGetPageDTO.getPageSize());
        page.getPage().setCurrentPage(deviceMediaGateBindAddressGetPageDTO.getCurrentPage());
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        //填充返回数据集
        List<DeviceMediaBindAddressVO> datas = iDeviceMediaGateDao.getPageOneMediaGateBindAddressInfos(params);
        page.setRows(datas,  iDeviceMediaGateDao.getMediaIdCount(deviceMediaGateBindAddressGetPageDTO.getMediaId()));
        return page;
    }

    /**
     * <desc>
     * 删除门口机多媒体资源-与指定地址的关系.
     * </desc>
     *
     * @param deviceMediaRemoveGateBindAddressDTO   需要删除的门口机多媒体资源关联的部分地址关系.
     * @return 受影响的行数
     * @author LewisLouis
     * @createDate 2017-11-23
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer removeMediaGateRelation(DeviceMediaRemoveGateBindAddressDTO deviceMediaRemoveGateBindAddressDTO) {
        return iDeviceMediaGateDao.removeMediaGateRelation(deviceMediaRemoveGateBindAddressDTO);

    }

    /**
     * <desc>
     *    将逗号分隔的源字符串转换为List.
     * </desc>
     *
     * @param sourceStr 逗号分隔的源字符串
     * @return String列表
     * @author LewisLouis
     * @createDate 2017-11-25
     */
    private List<String> castStrToListByCommaChar(String sourceStr){
        List<String> resultList;
        if (!StringUtils.isBlank(sourceStr)){
            resultList =  Arrays.asList(sourceStr.split(","));
        } else
        {
            resultList = new ArrayList<>();
        }
        return  resultList;
    }


}
